class ClientCache {
  private _storage: Storage

  constructor(nativeStorage: Storage) {
    this._storage = nativeStorage
  }

  isJson(val: string | undefined | null) {
    if (!val) {
      return false
    }

    return /(^\[.*\]$|^\{.*\}$)/.test(val)
  }

  parsable(val: string) {
    const isNum = /^\d+$/.test(val)
    const isBool = /true|false/.test(val)
    const isNull = /null/.test(val)
    const isJson = this.isJson(val)

    return isNum || isBool || isJson || isNull
  }

  get(key: string) {
    const val = this._storage.getItem(key)
    if (val && this.parsable(val)) {
      return JSON.parse(val) // true false number or data
    }

    return val
  }

  set(key: string, val: any) {
    if (
      Array.isArray(val) ||
      Object.prototype.toString.call(val).slice(8, -1) === 'Object'
    ) {
      return this._storage.setItem(key, JSON.stringify(val))
    }

    return this._storage.setItem(key, val === undefined ? null : val)
  }

  del(key: string) {
    this._storage.removeItem(key)
  }

  clear() {
    this._storage.clear()
  }
}

const LCache = new ClientCache(localStorage)
const SCache = new ClientCache(sessionStorage)

export { LCache, SCache }
